/*
 * UserPageTitledAddEditLink.java
 *
 *
 */

package net.kernub.client;

import com.google.gwt.core.client.GWT;

import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;

import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.HorizontalPanel;

import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.Hidden;
import com.google.gwt.user.client.ui.DialogBox;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyPressEvent;
import com.google.gwt.event.dom.client.KeyPressHandler;
import com.google.gwt.event.dom.client.KeyCodes;

import java.lang.Integer;
import java.util.ArrayList;

import net.kernub.client.core.RPC;
import net.kernub.client.core.RPCCallback;
import net.kernub.client.core.datatype.CInteger;
import net.kernub.client.core.datatype.CBoolean;

import net.kernub.client.www;
import net.kernub.client.wwwConstants;
import net.kernub.client.PageTitled;
import net.kernub.client.LabelData;

import net.kernub.client.datatype.LinkDesc;
import net.kernub.client.datatype.LabelDesc;
import net.kernub.client.datatype.LabelDescArray;

/*
 * UserPageTitledAddEditLink class
 */
public class UserPageTitledAddEditLink extends PageTitled
{
	private final wwwConstants constants = GWT.create( wwwConstants.class ); 

	private int linkID = -1;

	private final VerticalPanel mainPanel = new VerticalPanel();

	private final TextBox nameTextBox = new TextBox();
	private final TextBox urlTextBox = new TextBox();
	private final TextBox descTextBox = new TextBox();
	private final Button okButton = new Button( constants.ok() );

	private final FlexTable existingLabelsTable = new FlexTable();
	private final FlexTable assocLabelsTable = new FlexTable();

	private final ArrayList<LabelData> existingLabels = new ArrayList<LabelData>();
	private final ArrayList<LabelData> assocLabels = new ArrayList<LabelData>();

	public UserPageTitledAddEditLink()
	{
		createLinkDescPart();
		createLabelSelectPart();
		createButtonsPart();

		mainPanel.setSpacing( 15 );
		mainPanel.setWidth( "100%" );

		setContent( mainPanel );
	}

	public void setActive()
	{
		super.setActive();

		linkID = -1;
		nameTextBox.setText( "" );
		urlTextBox.setText( "" );
		descTextBox.setText( "" );
		okButton.setEnabled( true );
		existingLabels.clear();
		assocLabels.clear();
		existingLabelsTable.clear();
		assocLabelsTable.clear();

		int c = 0;
		c = existingLabelsTable.getRowCount();
		while( c > 0 ) existingLabelsTable.removeRow( --c );
		c = assocLabelsTable.getRowCount();
		while( c > 0 ) assocLabelsTable.removeRow( --c );

		setBigTitle( constants.linkAddMainTitle() );

		nameTextBox.setFocus( true );

		updateExistingLabels();
	}

	private void createLinkDescPart()
	{
		final Label titleLabel = new Label( constants.linkLinkDescPartTitle() );
		final Label nameLabel = new Label( constants.linkName() );
		final Label urlLabel = new Label( constants.linkUrl() );
		final Label descLabel = new Label( constants.linkDescription() );

		titleLabel.addStyleName( "PageSubTitle" );

		nameLabel.addStyleName( "PageText" );

		urlLabel.addStyleName( "PageText" );

		descLabel.addStyleName( "PageText" );

		nameTextBox.setVisibleLength( 10 );
		nameTextBox.setMaxLength( 255 );
		nameTextBox.addKeyPressHandler( new KeyPressHandler() {
			public void onKeyPress( KeyPressEvent event )
			{
				if( event.getCharCode() == KeyCodes.KEY_ENTER )
					urlTextBox.setFocus( true );
			}
		});

		urlTextBox.setVisibleLength( 45 );
		urlTextBox.setMaxLength( 255 );
		urlTextBox.addKeyPressHandler( new KeyPressHandler() {
			public void onKeyPress( KeyPressEvent event )
			{
				if( event.getCharCode() == KeyCodes.KEY_ENTER )
					descTextBox.setFocus( true );
			}
		});

		descTextBox.setVisibleLength( 45 );
		descTextBox.setMaxLength( 255 );

		final FlexTable formPanel = new FlexTable();
		formPanel.addStyleName( "PageSubContent" );
		formPanel.setWidget( 0, 0, nameLabel );
		formPanel.setWidget( 0, 1, nameTextBox );
		formPanel.setWidget( 1, 0, urlLabel );
		formPanel.setWidget( 1, 1, urlTextBox );
		formPanel.setWidget( 2, 0, descLabel );
		formPanel.setWidget( 2, 1, descTextBox );

		mainPanel.add( titleLabel );
		mainPanel.add( formPanel );
	}

	private void createLabelSelectPart()
	{
		final Label titleLabel = new Label( constants.linkAssocLabelPartTitle() );
		titleLabel.addStyleName( "PageSubTitle" );

		existingLabelsTable.setWidth( "100%" );
		existingLabelsTable.setCellSpacing( 5 );
		existingLabelsTable.getColumnFormatter().setWidth( 0, "90%" );
		existingLabelsTable.getColumnFormatter().setWidth( 1, "10%" );
		
		assocLabelsTable.setWidth( "100%" );
		assocLabelsTable.setCellSpacing( 5 );
		assocLabelsTable.getColumnFormatter().setWidth( 0, "90%" );
		assocLabelsTable.getColumnFormatter().setWidth( 1, "10%" );

		final FlexTable panel = new FlexTable();
		panel.setWidth( "100%" );
		panel.addStyleName( "PageSubContent" );
		panel.getColumnFormatter().setWidth( 0, "40%" );
		panel.getColumnFormatter().setWidth( 0, "40%" );
		panel.getColumnFormatter().setWidth( 1, "40%" );
		panel.setWidget( 0, 0, existingLabelsTable );
		panel.setWidget( 0, 1, assocLabelsTable );

		mainPanel.add( titleLabel );
		mainPanel.add( panel );
	}

	private void createButtonsPart()
	{
		final Button cancelButton = new Button( constants.cancel() );

		cancelButton.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				www.instance().setPage( www.PAGE_DISPLAY_LINKS );
			}
		});

		okButton.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				saveLink();
			}
		});

		final HorizontalPanel panel = new HorizontalPanel();
		panel.setWidth( "100%" );
		panel.add( cancelButton );
		panel.add( okButton );
		panel.setCellHorizontalAlignment( cancelButton, HorizontalPanel.ALIGN_CENTER );
		panel.setCellHorizontalAlignment( okButton, HorizontalPanel.ALIGN_CENTER );

		mainPanel.add( panel );
	}

	public void updateExistingLabels()
	{
		DeferredCommand.addCommand( new Command() {
			public void execute()
			{
				RPC.call( "site/Label", "getList", new RPCCallback<LabelDescArray>() {
					public void onCallback( LabelDescArray r )
					{
						for( int i = 0; i < r.labels().length(); i++ )
						{
							addExistingLabel( r.labels().get(i).getId(), r.labels().get(i).getName() );
						}
					}
				});
			}
		});
	}

	private void addExistingLabel( int id, String name )
	{
		final int row = existingLabelsTable.getRowCount();
		final LabelData label = new LabelData( id, name );
		final Label nameLabel = new Label( name );
		final Hyperlink plusLink = new Hyperlink();

		existingLabels.add( label );

		nameLabel.addStyleName( "PageText" );

		plusLink.setText( constants.linkPlus() );
		plusLink.addStyleName( "LinkCursor" );
		plusLink.addStyleName( "PageText" );
		plusLink.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				addAssocLabel( label.getID(), label.getName() );

				int index = existingLabels.indexOf( label );
				existingLabels.remove( index );
				existingLabelsTable.removeRow( index );
			}
		});

		existingLabelsTable.setWidget( row, 0, nameLabel );
		existingLabelsTable.setWidget( row, 1, plusLink );
	}

	private void addAssocLabel( int id, String name )
	{
		final int row = assocLabelsTable.getRowCount();
		final LabelData label = new LabelData( id, name );
		final Label nameLabel = new Label( name );
		final Hyperlink minusLink = new Hyperlink();

		assocLabels.add( label );

		nameLabel.addStyleName( "PageText" );

		minusLink.setText( constants.linkMinus() );
		minusLink.addStyleName( "LinkCursor" );
		minusLink.addStyleName( "PageText" );
		minusLink.addClickHandler( new ClickHandler() {
			public void onClick( ClickEvent event )
			{
				addExistingLabel( label.getID(), label.getName() );

				int index = assocLabels.indexOf( label );
				assocLabels.remove( index );
				assocLabelsTable.removeRow( index );
			}
		});

		assocLabelsTable.setWidget( row, 0, nameLabel );
		assocLabelsTable.setWidget( row, 1, minusLink );
	}

	public void loadLink( final int id )
	{
		DeferredCommand.addCommand( new Command() {
			public void execute()
			{
				RPC.call( "site/Link", "get", id, new RPCCallback<LinkDesc>() {
					public void onCallback( LinkDesc l )
					{
						linkID = id;
						nameTextBox.setText( l.getName() );
						urlTextBox.setText( l.getURL() );
						descTextBox.setText( l.getDescription() );

						for( int i = 0; i < l.getLabels().length(); i++ )
						{
							addAssocLabel( l.getLabels().get(i).getId(), l.getLabels().get(i).getName() );

							// we look over existing link to remove them
							for( LabelData ld : existingLabels )
							{
								if( ld.getID() == l.getLabels().get(i).getId() )
								{
									int index = existingLabels.indexOf( ld );
									existingLabels.remove( index );
									existingLabelsTable.removeRow( index );
								}
							}
						}
					}
				});
			}
		});
	}

	private void saveLink()
	{
		final ArrayList<Integer> ids = new ArrayList<Integer>();
		for( LabelData label : assocLabels )
			ids.add( label.getID() );

		if( linkID <= -1 )
		{
			okButton.setEnabled( false );

			RPC.call( "site/Link", "add", nameTextBox.getText(), urlTextBox.getText(), descTextBox.getText(), ids,
								new RPCCallback<CInteger>() {
				public void onCallback( CInteger r )
				{
					okButton.setEnabled( true );
					if( r.get() >= 0 )
					{
						www.instance().setPage( www.PAGE_DISPLAY_LINKS );
					}
					else
					{
						setTempInfo( constants.linkSaveError() );
					}
				}
			});
		}
		else
		{
			okButton.setEnabled( false );

			RPC.call( "site/Link", "update", linkID, nameTextBox.getText(), urlTextBox.getText(), descTextBox.getText(), ids,
								new RPCCallback<CBoolean>() {
				public void onCallback( CBoolean r )
				{
					okButton.setEnabled( true );
					if( r.get() )
					{
						www.instance().setPage( www.PAGE_DISPLAY_LINKS );
					}
					else
					{
						setTempInfo( constants.linkSaveError() );
					}
				}
			});
		}
	}

}

